
package com.lavida.project.wage.controller;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane.IconifyAction;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.databind.util.ArrayBuilders.DoubleBuilder;
import com.lavida.common.utils.BigDecimalUtil;
import com.lavida.common.utils.CalcRate;
import com.lavida.common.utils.StringUtils;
import com.lavida.common.utils.poi.ExcelUtil;
import com.lavida.common.utils.security.ShiroUtils;
import com.lavida.framework.aspectj.lang.annotation.Log;
import com.lavida.framework.aspectj.lang.enums.BusinessType;
import com.lavida.framework.web.controller.BaseController;
import com.lavida.framework.web.domain.AjaxResult;
import com.lavida.framework.web.page.TableDataInfo;
import com.lavida.project.attendance.domain.Attendance;
import com.lavida.project.companymanager.domain.EmpInformation;
import com.lavida.project.companymanager.service.EmpInformationService;
import com.lavida.project.system.attendance.domain.Attendances;
import com.lavida.project.system.attendance.domain.Attendancess;
import com.lavida.project.system.emp.domain.Emp;
import com.lavida.project.system.performance.domain.Performance;
import com.lavida.project.wage.domain.Merits;
import com.lavida.project.wage.domain.NewWageAccount;
import com.lavida.project.wage.service.NewWageAccountService;

import net.sf.ehcache.search.aggregator.Sum;

/**
 * 核算新工资
 * 
 */
@Controller
@RequestMapping("/wage/newwageaccount")
public class NewWageAccountController extends BaseController{
    private String prefix = "wage/newwageaccount";

    @Autowired
    private NewWageAccountService newWageAccountService;
    
    @Autowired
    private EmpInformationService empInformationService;

    //@RequiresPermissions("wage:newwageaccount:view")
    @GetMapping()
    public String newwageaccount(ModelMap mmap,@RequestParam(name="year",required=false) String year,@RequestParam(name="month",required=false) String month)
    {
    	mmap.put("user", ShiroUtils.getSysUser());
    	mmap.put("year", year);
    	mmap.put("month", month);
        return prefix + "/newwageaccount";
    }
    
    
    @RequiresPermissions("payroll:newwage:add")
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    @RequiresPermissions("payroll:newwage:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(NewWageAccount newWageAccount,HttpServletRequest request){	
    	List<NewWageAccount> list = new ArrayList<NewWageAccount>();
    	Long selectNewWageAccountTotal = newWageAccountService.selectNewWageAccountTotal(newWageAccount);
    	startPage(); 
    	 //分页插件方法 ，只会对该语句以后的第一个查询（Select）语句得到的数据进行分页。
    	System.out.println(">>>>>>>>>>>>>>>>>>有工号:"+selectNewWageAccountTotal);
    	Double performanceee = 0.0;
    	Double jiaban = 0.0;
    	Double deductCost1 = 0.0;
    	//如果该月有数据，工号就从薪资核算表中抓取
    	if(selectNewWageAccountTotal>0) {
    		
    		list= newWageAccountService.selectNewWageAccountList(newWageAccount);
    		System.out.println("数据:"+list.toString());
    		for(NewWageAccount newWageAccount2:list) {
    			
    			//核算表有了绩效值，将值赋给绩效队形
    			Performance performances = newWageAccount2.getPerformances();
    			// 如果对象实体类为空，则实体类的属性没有，取不到属性值，所以报null异常
    			if(performances!=null) {        
					/*System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>绩效:"+performances);*/
    				Double performancee = performances.getPerformancee();
    				if(performancee==null) {
    					performancee = 0.0;
    				}
    				performanceee = performancee;
    				newWageAccount2.setPerformance(performancee);
    			}else {
    				newWageAccount2.setPerformance(0.0);
    			}
				/*System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>绩效:"+performancee);*/
    			//考勤统计：计算加班费用、减除费用
    			//税前收入
    			Double taxBefore = newWageAccount2.getEmp().getTaxbefore();
    			if(taxBefore==null) {
    				taxBefore = 0.0;	
    			}
    			System.out.println("状态："+newWageAccount2.getEmp().getStatus());
    			if(newWageAccount2.getEmp().getStatus().equals("试用期")) {
    				taxBefore = taxBefore * 0.8;
    			}
    			newWageAccount2.getEmp().setTaxbefore(taxBefore);
    			System.out.println("税前收入》》。。。"+taxBefore);
    			//小时工资
    			Double hourSalary = BigDecimalUtil.div(taxBefore, (21.75*8),2).doubleValue();
    			System.out.println("小时工资"+hourSalary);
    			Attendancess attendenceOne = newWageAccount2.getAttendancess();
    			if(attendenceOne!=null) {
					Double workg = attendenceOne.getWorkg();
					System.out.println("工作日加班》》》》》》》》》"+workg);
	    			if(workg==null) {
	    				workg = 0.0;
	    			}
	    			Double workx= attendenceOne.getWorkx();
					System.out.println("休息日加班》》》》》》》》》"+workx);
	    			if(workx==null) {
	    				workx = 0.0;
	    			}
	    			Double workj = attendenceOne.getWorkj();
					System.out.println("节假日加班》》》》》》》》》"+workj);
	    			if(workj==null) {
	    				workj = 0.0;
	    			}
	    			//加班工资 = 加班 * 小时工资 *1.5
	    			Double overtimeCost = workg * hourSalary * 1.5 + workx * hourSalary * 1 + workj * hourSalary * 3;
	    			newWageAccount2.setOvertimeCost(overtimeCost);
	    			System.out.println("加班>>>>>>>>>>>>"+overtimeCost);
	    			jiaban = overtimeCost;
	    			//迟到次数
	    			Double latenumber = attendenceOne.getLatenumber();
	    			if(latenumber==null) {
	    				latenumber = 0.0;
	    			}
	    			Double serouslatenumber = attendenceOne.getSerouslatenumber();
	    			if(serouslatenumber==null) {
	    				serouslatenumber = 0.0;
	    			}
	    			//迟到时长
	    			Double latetime = attendenceOne.getLatetime();
	    			if(latetime ==null) {
	    				latetime = 0.0;
	    			}
	    			//早退次数
	    			Double earlynumber = attendenceOne.getEarlynumber();
	    			if(earlynumber == null) {
	    				earlynumber = 0.0;
	    			}
	    			//严重早退次数
	    			Double seearlynumber = attendenceOne.getSeearlynumber();
	    			if(seearlynumber==null) {
	    				seearlynumber = 0.0;
	    			}
	    			//严重迟到时长
	    			Double earlytime = attendenceOne.getEarlytime();
	    			if (earlytime == null) {
						earlytime = 0.0;
					}
	    			//旷工时长
	    			Double kgtime = attendenceOne.getKgtime();
	    			if(kgtime == null) {
	    				kgtime = 0.0;
	    			}
	    			//年假
	    			Double review = attendenceOne.getReview();
	    			if(review == null) {
	    				kgtime = 0.0;
	    			}
	    			//病假
	    			Double sick = attendenceOne.getKgtime();
	    			if(sick == null) {
	    				sick = 0.0;
	    			}
	    			//事假
	    			Double shijia = attendenceOne.getShijia();
	    			if(shijia == null) {
	    				shijia = 0.0;
	    			}
	    			//减除 = 迟到时长次数 * 30  + 严重迟到次数 * 70  + 旷工迟到天数 *8 *小时工资  + 早退次数 * 30 + 早退旷工天数 * 3 *小时工资 + 病假 * 0.3 *小时工资 + 事假（天）*8 * 小时工资
	    			Double deductCost = latenumber*30+serouslatenumber*70+kgtime*hourSalary*3+earlynumber*30+seearlynumber*hourSalary*3+sick*hourSalary*0.3+shijia*hourSalary;
	    			newWageAccount2.setDeductCost(deductCost);
	    			System.out.println("》》》》》》》》>减除"+deductCost);
	    			deductCost1 = deductCost ;
	    			//核算表有了核算值，将值赋值给考勤类
	    			
	    			/*newWageAccount2.setWorkHours(workHours);
	    			System.out.println("workHours>>>>>>>>>>>>>>>>>"+workHours);*/
	    			
	    			
    			}else {
    				newWageAccount2.setWorkHours(0.0);
    				newWageAccount2.setRestDays(0.0);
    				newWageAccount2.setYcqts(0.0);
    				newWageAccount2.setOvertimeCost(0.0);
    				newWageAccount2.setDeductCost(0.0);
    			}
    			Emp emp = newWageAccount2.getEmp();
    			Integer job_id = emp.getJob_id();
    			
    			//个人养老金
    			Double personalPension = emp.getBasicoldpercost();
    			if(personalPension == null) {
    				personalPension = 0.0;
    			}
    			//个人医疗保险
    			Double personalMI = emp.getBasicdocpercost();
    			if(personalMI == null) {
    				personalMI = 0.0;
    			}
    			//个人失业保险
    			Double personalBI = emp.getUnemploymentpercost();
    			if(personalBI == null) {
    				personalBI = 0.0;
    			}
    			//个人公积金
    			Double personalAF = emp.getProvidentfundpercost();
    			if(personalAF == null) {
    				personalAF = 0.0;
    			}
    			//公司养老保险
    			Double companyPension = emp.getBasicoldcomcost();
    			if(companyPension == null) {
    				companyPension = 0.0;
    			}
    			//公司医疗保险
    			Double companyMI = emp.getBasicdoccomcost();
    			if(companyMI == null) {
    				companyMI = 0.0;
    			}
    			//公司地方附加医疗保险
    			Double companyLAMI = emp.getLocaldoccomcost();
    			if(companyLAMI == null) {
    				companyLAMI = 0.0;
    			}
    			//公司失业保险
    			Double companyBI = emp.getUnemploymentcomcost();
    			if(companyBI == null) {
    				companyBI = 0.0;
    			}
    			//公司工伤保险
    			Double companyII = emp.getMateryinsurancecomcost();
    			if(companyII == null) {
    				companyII = 0.0;
    			}
    			//公司残疾保险
    			Double companyCI = emp.getDisableinsurancecomcost();
    			if(companyCI == null) {
    				companyCI = 0.0;
    			}
    			//公司公积金保险
    			Double companyDI = emp.getProvidentfundcomcost();
    			if(companyDI == null) {
    				companyDI = 0.0;
    			}
    			Double sum =emp.getPersonsumpay();
    			if (sum==null) {
					sum = 0.0;
				}
    			//个人应交费用
    			
    			Double personsum = emp.getPersonsumpay();
    			if (personsum==null) {
					personsum = 0.0;
				}
    			Double person = personsum - personalAF;
    			BigDecimal personpa= new BigDecimal(person);
    			personpa = personpa.setScale(1,RoundingMode.UP);
    			Double personpay = Double.parseDouble(personpa.toString());
    			emp.setPersonsumpay(personpay);
    			//公司应交费用
    			Double comsonsumpay = emp.getCompanysumpay();
    			if (comsonsumpay==null) {
					comsonsumpay = 0.0;
				}
    			Double companysum	= comsonsumpay - companyDI;
    			String  comnpa= String.format("%.2f", companysum);
    			Double compay = Double.parseDouble(comnpa);
    			emp.setCompanysumpay(compay);
    			System.out.println("姓名"+emp.getName());
    			//基本工资
    			Double basesalary = emp.getBasesalary();
    			if(basesalary==null) {
    				basesalary = 0.00;
    			}
    			if (emp.getStatus().equals("试用期")) {
					basesalary = basesalary * 0.8;
				}else {
					basesalary = basesalary;
				}
    			emp.setBasesalary(basesalary);
    			System.out.println("基本工资：》》》》》》》》》》》》》"+basesalary);
    			//工龄工资
    			Double standsalary = emp.getStandsalary();
    			if(standsalary==null) {
    				standsalary = 0.00;
    			}
    			if (emp.getStatus().equals("试用期")) {
					standsalary = standsalary * 0.8;
				}else {
					standsalary = standsalary;
				}
    			emp.setStandsalary(standsalary);
    			//资历工资
    			Double quasalary = emp.getQuasalary();
    			if (quasalary==null) {
    				quasalary = 0.00;
    			}
    			if (emp.getStatus().equals("试用期")) {
					quasalary = quasalary * 0.8;
				}else {
					quasalary = quasalary;
				}
    			emp.setQuasalary(quasalary);
    			//岗位工资
    			Double postsalary = emp.getPostsalary();
    			if (postsalary==null) {
    				postsalary = 0.00;
    			}
    			if (emp.getStatus().equals("试用期")) {
					postsalary = postsalary * 0.8;
				}else {
					postsalary = postsalary;
				}
    			emp.setPostsalary(postsalary);
    			//岗位津贴
    			Double postsubsidy = emp.getPostsubsidy();
    			if (postsubsidy==null) {
    				postsubsidy = 0.0;
    			}
    			if (emp.getStatus().equals("试用期")) {
					postsubsidy = postsubsidy * 0.8;
				}else {
					postsubsidy = postsubsidy;
				}
    			emp.setPostsubsidy(postsubsidy);
    			//其它增减
    			Double other = newWageAccount2.getOtherCrease();
    			if (other==null) {
    				other = 0.00;
    			}
    			newWageAccount2.setOtherCrease(other);
    			
    			//其它津贴
    			Double otherAllowance = newWageAccount2.getOtherAllowance();
    			if (otherAllowance==null) {
					otherAllowance = 0.00;
				}
    			System.out.println("其它津贴"+otherAllowance);
    			//不计税收入
    			Double nonTaxIncome = newWageAccount2.getNonTaxIncome();
    			
    			String istax = newWageAccount2.getIsTax();
    			if(istax!=null){
    				try {
    					int i = Integer.valueOf(istax) ;
    					if(i==1) {
        					nonTaxIncome = otherAllowance;
        					newWageAccount2.setNonTaxIncome(nonTaxIncome);
        				}else {
        					nonTaxIncome = 0.00;
        					newWageAccount2.setNonTaxIncome(nonTaxIncome);
        				}
    				}catch (NumberFormatException e) {
						// TODO: handle exception
    					e.addSuppressed(new Exception("数字转换错误"));
    					nonTaxIncome = 0.00;
    					newWageAccount2.setNonTaxIncome(nonTaxIncome);
					}
				}else {
					nonTaxIncome = 0.00;
					newWageAccount2.setNonTaxIncome(nonTaxIncome);
					
				}
    			System.out.println(istax);
    			System.out.println(istax=="不计税");
    			System.out.println("加班"+jiaban);
    			System.out.println("减除"+deductCost1);
    			

    			DecimalFormat df = new DecimalFormat("#.00");
    			//工资汇总 = 基本工资 + 工龄工资 + 资历工资 + 岗位工资
    			Double preTaxTotalIncome = basesalary + standsalary + quasalary + postsalary + postsubsidy;
    			//汇总税前总收入 = 工资汇总  + 绩效 + 加班+ + 其它增减 +其它津贴 - 减除 
    			preTaxTotalIncome =  preTaxTotalIncome + other + otherAllowance + performanceee + jiaban - deductCost1;
    			System.out.println("汇总税前总收入"+preTaxTotalIncome);
    			String preson = df.format(preTaxTotalIncome);
    			BigDecimal dg = new BigDecimal(preTaxTotalIncome);
    			Double preess = dg.setScale(2,RoundingMode.HALF_UP).doubleValue();
    			//汇总工资
    			/*Double preTaxTotalIncome = basesalary + standsalary + postsalary + postsubsidy;*/
    			System.out.println("preTaxTotalIncome>>>>>>>>>>>>>>>>>>>>"+preTaxTotalIncome);
    			newWageAccount2.setPreTaxTotalIncome(preess);
    			
    			//转账工资税前上限
    			Double salarytrans = emp.getSalarytrans();
    			if(salarytrans== null || salarytrans==0.0) {
					salarytrans = 0.0;
				}
    			
    			if (salarytrans<=basesalary) {
					salarytrans = basesalary;
				}else {
					salarytrans = basesalary;
				}
    			
    			newWageAccount2.setEmp(emp);
    			System.out.println("工资转账上限：》》》》》》》》》》》》》"+salarytrans);
    			//传入的月份
    			int months =Integer.valueOf(newWageAccount2.getMonth());
    			//转账税前工资
    			Double basePay = 0.00;
    			if (preTaxTotalIncome<salarytrans) {
    				basePay = preTaxTotalIncome;
				}else if(salarytrans<=preTaxTotalIncome){
					basePay = salarytrans;
				}else {
					basePay = salarytrans;
				}
    			newWageAccount2.setBasePay(basePay);
    			System.out.println("转账税前工资"+basePay);
    			
    			String isTax = newWageAccount2.getIsTax();
    		
    			//个税
    			Double personIncomeTax = CalcRate.geshui(basePay, sum,0.0,months);
    			String persons = df.format(personIncomeTax);
    			Double persondd = Double.parseDouble(persons);
    			System.out.println("个税:"+personIncomeTax);
    			newWageAccount2.setPersonIncomeTax(personIncomeTax);
    		
    			//转账工资 = 转账税前工资 - 个税 - 个人社保 - 个人公积金
    			Double payableWages = basePay - personIncomeTax - sum;
    			System.out.println("转账工资"+payableWages);
    			String pa = df.format(payableWages);
    			Double payablewas = Double.parseDouble(pa);
    			System.out.println(payablewas);
    			newWageAccount2.setPayableWages(payablewas);
    			
    			/*//生成转账工资  = 生成应付工资 + 不计税收入 - 社保公积金总和
    			Double transAccount = payableWages + nonTaxIncome - sum;
    			String tranAcound = df.format(transAccount);
    			Double tranAccons = Double.parseDouble(tranAcound);
    			System.out.println("转账工资L:"+tranAccons);
    			newWageAccount2.setTransAccount(tranAccons);*/
    			//现金工资 = 汇总税前总收入 - 转账工资 - 不计税收入
    			Double cashWage = preTaxTotalIncome - basePay - nonTaxIncome;	
    			System.out.println("现金："+cashWage +"="+ preTaxTotalIncome +" -"+ basePay+"-"+"-"+nonTaxIncome);
    			String cashw = df.format(cashWage);
    			Double cashwages = Double.parseDouble(cashw);
    			newWageAccount2.setCashWage(cashwages);
    			System.out.println("工资核算："+attendenceOne);
    			newWageAccount2.setJobNum(job_id);
    			
    			newWageAccount2.setAttendancess(attendenceOne);
    			
    		}
    	}else {
    		list = newWageAccountService.selectEmpInfoNewWageAccountList(newWageAccount);
    		System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>无工号"+list.toString());
    	}
        return getDataTable(list);
    }
    
    @RequiresPermissions("payroll:newwage:add")
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult add(@RequestBody List<NewWageAccount> newWageAccountList)
    {
    	System.out.println(newWageAccountList);
        try
        {
            return toAjax(newWageAccountService.addNewWageAccountList(newWageAccountList));
        }
        catch (Exception e)
        {
        	e.printStackTrace();
            return error(e.getMessage());
        }
    }
    
    @Log(title = "工资单", businessType = BusinessType.EXPORT)
	@PostMapping("/export")
	@ResponseBody
	@RequiresPermissions("payroll:newwage:export")
	public AjaxResult export(NewWageAccount newWageAccount) {
		List<NewWageAccount> list = newWageAccountService.selectNewWageAccountList(newWageAccount);
		ExcelUtil<NewWageAccount> util = new ExcelUtil<NewWageAccount>(NewWageAccount.class);
		return util.exportExcel(list, "工资单");
	}
    
    
    


    /**
     * 修改保存
     */
   /* @RequiresPermissions("wage:newwageaccount:edit")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(@Validated User user)
    {
        userService.checkUserAllowed(user);
        if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
        {
            return error("修改用户'" + user.getLoginName() + "'失败，手机号码已存在");
        }
        else if (UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
        {
            return error("修改用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        } 
        //该部门已经有部门领导，不是本人，不允许修改
        String deptLeader = userMapper.selectDeptLeaderId("deptLeader", user.getDeptId());
        if(Arrays.asList(user.getRoleIds()).contains(100L) && StringUtils.isNotBlank(deptLeader) && !user.getLoginName().equals(deptLeader)) {
        	return error("修改用户'" + user.getLoginName() + "'失败，该部门已经有一位用户的角色为部门领导");
        }
        return toAjax(userService.updateUser(user));
    }*/

  /*  @RequiresPermissions("wage:newwageaccount:remove")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        try
        {
            return toAjax(userService.deleteUserByIds(ids));
        }
        catch (Exception e)
        {
            return error(e.getMessage());
        }
    }*/

   
    
}